<template>
	<view class="container">
		<canvas canvas-id="gestureCanvas" class="gesture-canvas" disable-scroll @touchstart="handleTouchStart"
			@touchmove="handleTouchMove" @touchend="handleTouchEnd"></canvas>
		<view class="tips">{{ tipsText }}</view>
	</view>
</template>

<script setup>
	import {ref, onMounted, nextTick} from 'vue'

	// 响应式数据
	const points = ref([])
	const currentPath = ref([])
	const tipsText = ref('请绘制手势密码')
	const ctx = ref(null)
	const canvasPos = ref({
		left: 0,
		top: 0
	})
	const canvasWidth = ref(300)

	// 初始化九宫格
	const initGrid = () => {
		const size = 3
		const cellSize = canvasWidth.value / (size + 1)

		points.value = []
		for (let i = 0; i < size; i++) {
			for (let j = 0; j < size; j++) {
				points.value.push({
					x: cellSize * (j + 1),
					y: cellSize * (i + 1),
					index: i * size + j
				})
			}
		}
	}

	// 绘制九宫格
	const drawGrid = () => {
		if (!ctx.value) return

		// 清除画布
		ctx.value.clearRect(0, 0, canvasWidth.value, canvasWidth.value)

		// 绘制点
		points.value.forEach(point => {
			ctx.value.beginPath()
			ctx.value.arc(point.x, point.y, canvasWidth.value / 20, 0, Math.PI * 2)
			ctx.value.fillStyle = '#e0e0e0'
			ctx.value.fill()

			// 高亮已选中的点
			if (currentPath.value.some(p => p.index === point.index)) {
				ctx.value.beginPath()
				ctx.value.arc(point.x, point.y, canvasWidth.value / 25, 0, Math.PI * 2)
				ctx.value.fillStyle = '#007AFF'
				ctx.value.fill()
			}
		})

		// 绘制连线
		if (currentPath.value.length > 0) {
			ctx.value.beginPath()
			ctx.value.moveTo(currentPath.value[0].x, currentPath.value[0].y)
			currentPath.value.forEach(point => {
				ctx.value.lineTo(point.x, point.y)
			})
			ctx.value.strokeStyle = '#007AFF'
			ctx.value.lineWidth = canvasWidth.value / 60
			ctx.value.stroke()
		}

		// 执行绘制
		ctx.value.draw(true) // 使用 true 保留上一次绘制
	}

	// 获取Canvas位置和尺寸
	const initCanvas = async () => {
		return new Promise(resolve => {
			uni.createSelectorQuery()
				.select('.gesture-canvas')
				.boundingClientRect(data => {
					if (data) {
						// 设置 Canvas 宽度为屏幕宽度的 80%，最大不超过 400px
						canvasWidth.value = Math.min(data.width, 400)
						canvasPos.value = {
							left: data.left,
							top: data.top
						}
					}
					resolve()
				})
				.exec()
		})
	}

	// 检查触摸点
	const checkTouchPoint = (touch) => {
		const x = touch.pageX - canvasPos.value.left
		const y = touch.pageY - canvasPos.value.top

		points.value.forEach(point => {
			const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2)
			// 动态计算触摸范围
			const touchRadius = canvasWidth.value / 15

			if (distance < touchRadius && !currentPath.value.some(p => p.index === point.index)) {
				currentPath.value.push(point)
			}
		})
	}

	// 触摸事件处理
	const handleTouchStart = async (e) => {
		await initCanvas()
		currentPath.value = []
		checkTouchPoint(e.touches[0])
		drawGrid()
	}

	const handleTouchMove = (e) => {
		// 阻止页面滚动
		e.preventDefault()
		checkTouchPoint(e.touches[0])
		drawGrid()
	}

	const handleTouchEnd = () => {
		if (currentPath.value.length < 4) {
			tipsText.value = '至少需要连接4个点'
			currentPath.value = []
			drawGrid()
			return
		}

		const password = currentPath.value.map(p => p.index).join('')

		// 首次设置密码
		if (!uni.getStorageSync('gesturePassword')) {
			uni.setStorageSync('gesturePassword', password)
			tipsText.value = '手势密码已保存，请重新绘制确认'
			currentPath.value = []
			drawGrid()
			return
		}

		// 验证密码
		if (password === uni.getStorageSync('gesturePassword')) {
			tipsText.value = '验证成功，正在登录...'
			login()
		} else {
			tipsText.value = '手势错误，请重试'
			currentPath.value = []
			drawGrid()
		}
	}

	// 登录逻辑
	const login = async () => {
		console.log(currentPath.value)
		try {
			// 实际项目中替换为你的登录API
			const [error, res] = await uni.request({
				url: '/api/login',
				method: 'POST',
				data: {
					gesture: currentPath.value.map(p => p.index).join('')
				}
			})

			if (res?.data?.success) {
				uni.showToast({title: '登录成功'})
				// 跳转到首页
				uni.switchTab({url: '/pages/index/index'})
			} else {
				uni.showToast({title: '登录失败',icon: 'none'})
				currentPath.value = []
				drawGrid()
			}
		} catch (error) {
			uni.showToast({title: '网络错误',icon: 'none'})
			currentPath.value = []
			drawGrid()
		}
	}

	// 组件挂载时初始化
	onMounted(async () => {
		await nextTick()
		ctx.value = uni.createCanvasContext('gestureCanvas')
		await initCanvas()
		initGrid()
		drawGrid()
	})
</script>

<style scoped>
	/* 全局阻止缩放 */
	page {
		touch-action: manipulation;
		-webkit-user-select: none;
		user-select: none;
		-webkit-touch-callout: none;
	}

	.container {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		height: 100vh;
		background-color: #f5f5f5;
	}

	.gesture-canvas {
		width: 300px;
		height: 500rpx;
		background-color: #fff;
		border-radius: 16px;
		box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);

		/* 阻止默认触摸行为 */
		touch-action: none;
		-webkit-tap-highlight-color: transparent;
	}

	.tips {
		margin-top: 24px;
		color: #666;
		font-size: 16px;
		text-align: center;
		padding: 0 20px;
	}

	/* 针对 iOS 的额外优化 */
	@supports (-webkit-touch-callout: none) {
		.gesture-canvas {
			-webkit-user-drag: none;
		}
	}
</style>